package handler

import (
	"ehsm_kms/api"
	"ehsm_kms/internal/apis"
	"ehsm_kms/internal/repository"
	"errors"
	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
)

type Handler struct {
	log        *zap.Logger
	userRep    repository.UserInfoRepository
	cmkRep     repository.CmkRepository
	quoteRep   repository.QuotePolicyRepository
	actionMaps map[apis.Action]func(ctx *gin.Context)
}

func NewHandler(log *zap.Logger, userRep repository.UserInfoRepository, cmkRep repository.CmkRepository, quoteRep repository.QuotePolicyRepository) *Handler {
	h := new(Handler)
	h.actionMaps = map[apis.Action]func(ctx *gin.Context){
		//get
		apis.GetVersion: h.getVersion,
		apis.Enroll:     h.enroll,

		//crypto_graphic
		apis.CreateKey:                       h.createKey,
		apis.Encrypt:                         h.encrypt,
		apis.Decrypt:                         h.decrypt,
		apis.AsymmetricEncrypt:               h.asymmetricEncrypt,
		apis.AsymmetricDecrypt:               h.asymmetricDecrypt,
		apis.GenerateDataKey:                 h.generateDataKey,
		apis.GenerateDataKeyWithoutPlaintext: h.generateDataKeyWithoutPlaintext,
		apis.ExportDataKey:                   h.exportDataKey,
		apis.Sign:                            h.sign,
		apis.Verify:                          h.verify,
		apis.GetPublicKey:                    h.getPublicKey,

		//key_management
		apis.ListKey:      h.listKey,
		apis.DeleteKey:    h.deleteKey,
		apis.DeleteAllKey: h.deleteAllKey,
		apis.EnableKey:    h.enableKey,
		apis.DisableKey:   h.disableKey,
	}
	h.log = log
	h.userRep = userRep
	h.cmkRep = cmkRep
	h.quoteRep = quoteRep
	return h
}

func (h *Handler) GET(ctx *gin.Context) {
	h.routes(ctx)
}

func (h *Handler) POST(ctx *gin.Context) {
	h.routes(ctx)
}

func (h *Handler) routes(ctx *gin.Context) {
	action, _ := ctx.GetQuery("action")
	if f, ok := h.actionMaps[apis.Action(action)]; ok {
		f(ctx)
		return
	}
	api.HandleError(ctx, 404, errors.New("not found"), nil)
}

type Req struct {
	Appid   string         `json:"appid" binding:"required"`
	Payload map[string]any `json:"payload,omitempty" binding:"omitempty"`
}
